package com.zone.trigger.http;

import cn.hutool.core.bean.BeanUtil;
import com.google.common.collect.Lists;
import com.zone.domain.acticity.model.entity.ActivityEntity;
import com.zone.domain.acticity.model.entity.RaffleActivityAccountEntity;
import com.zone.domain.acticity.service.ActivitySupport;
import com.zone.domain.acticity.service.IActivityOrderQuota;
import com.zone.domain.strategy.model.entity.*;
import com.zone.domain.strategy.model.valobj.RuleEnums;
import com.zone.domain.strategy.model.valobj.RuleTreeEnums;
import com.zone.domain.strategy.service.IRaffleAward;
import com.zone.domain.strategy.service.IRaffleRule;
import com.zone.domain.strategy.service.IRaffleStrategy;
import com.zone.domain.strategy.service.armory.IStrategyArmory;
import com.zone.trigger.api.IRaffleStrategyService;
import com.zone.trigger.api.dto.*;
import com.zone.types.exception.BizException;
import com.zone.types.model.Response;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.logging.log4j.util.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author: zongzi
 * @description: 营销抽奖服务
 * @date: 2024/6/17
 */
@CrossOrigin("${app.config.cross-origin}")
@RestController
@RequestMapping("/api/${app.config.api-version}/raffle")
@DubboService(version = "1.0")
public class RaffleStrategyController implements IRaffleStrategyService {
    @Autowired
    private IStrategyArmory strategyArmory;
    @Resource
    private IRaffleStrategy raffleStrategy;
    @Autowired
    private IRaffleAward raffleAward;
    @Autowired
    private IRaffleRule raffleRule;
    @Autowired
    private IActivityOrderQuota activityOrderQuota;
    @Autowired
    private ActivitySupport activitySupport;

    /**
     * 策略装配
     *
     * @param strategyId 策略id
     * @return 装配结果
     */
    @GetMapping("/strategy_armory")
    @Override
    public Response<Boolean> assembleStrategy(@RequestParam Long strategyId) {
        strategyArmory.assembleLotteryStrategy(strategyId);
        return Response.success(true);
    }

    /**
     * 查询奖品列表
     *
     * @param queryDTO 入参
     * @return 奖品列表
     */
    @GetMapping("/query_raffle_award_list")
    @Override
    public Response<List<StrategyAwardDTO>> queryStrategyAwardList(StrategyAwardQueryDTO queryDTO) {
        List<StrategyAwardEntity> strategyAwards = raffleAward.queryStrategyAwardList(queryDTO.getStrategyId());
        List<StrategyAwardDTO> strategyAwardDTOList = strategyAwards.stream()
                .map(strategyAwardEntity -> StrategyAwardDTO.builder()
                        .awardId(strategyAwardEntity.getAwardId())
                        .awardTitle(strategyAwardEntity.getAwardTitle())
                        .awardSubTitle(strategyAwardEntity.getAwardSubtitle())
                        .sort(strategyAwardEntity.getSort())
                        .build())
                .collect(Collectors.toList());
        return Response.success(strategyAwardDTOList);
    }

    /**
     * 查询奖品列表（根据活动查询）
     *
     * @param queryDTO 入参
     * @return 奖品列表
     */
    @PostMapping("/query_activity_raffle_award_list")
    @Override
    public Response<List<StrategyAwardDTO>> queryActivityRaffleAwardList(@RequestBody StrategyAwardActivityQueryDTO queryDTO) {
        // 参数校验
        if (Objects.isNull(queryDTO.getActivityId())) {
            throw new BizException("活动id不能为空");
        }
        if (Strings.isBlank(queryDTO.getUserId())) {
            throw new BizException("用户id不能为空");
        }
        // 查询奖品列表
        List<StrategyAwardEntity> strategyAwards = raffleAward.queryStrategyAwardListByActivityId(queryDTO.getActivityId());
        // 查询奖品规则树
        Long strategyId = strategyAwards.stream().map(StrategyAwardEntity::getStrategyId).findFirst().orElse(null);
        Map<Integer, List<RuleTreeNodeEntity>> awardTreeNodeMap = raffleRule.queryAwardTreeNodeMap(strategyId);
        // 查询用户抽奖次数（用户日账户表总次数 - 剩余次数）
        Integer userRaffleCount = activityOrderQuota.queryUserDayRaffleCount(queryDTO.getUserId(), queryDTO.getActivityId());
        // 构造返回值
        List<StrategyAwardDTO> strategyAwardDTOList = strategyAwards.stream()
                .map(strategyAwardEntity -> {
                    StrategyAwardDTO strategyAwardDTO = StrategyAwardDTO.builder()
                            .awardId(strategyAwardEntity.getAwardId())
                            .awardTitle(strategyAwardEntity.getAwardTitle())
                            .awardSubTitle(strategyAwardEntity.getAwardSubtitle())
                            .sort(strategyAwardEntity.getSort())
                            .build();
                    // 查询奖品-是否有配置rule_lock
                    RuleTreeNodeEntity firstTreeNode = awardTreeNodeMap.getOrDefault(strategyAwardEntity.getAwardId(), Lists.newArrayList())
                            .stream()
                            .filter(ruleTreeNodeEntity -> RuleTreeEnums.RuleKey.RULE_LOCK.getCode().equals(ruleTreeNodeEntity.getRuleKey()))
                            .findFirst()
                            .orElse(null);
                    if (Objects.isNull(firstTreeNode)) {
                        strategyAwardDTO.setIsLock(false);
                    } else {
                        Integer ruleLockCount = Integer.valueOf(firstTreeNode.getRuleValue());
                        strategyAwardDTO.setRuleLockCount(ruleLockCount);
                        strategyAwardDTO.setIsLock(userRaffleCount < ruleLockCount);
                        // 剩余抽奖次数
                        int waitUnCount = userRaffleCount < ruleLockCount ? ruleLockCount - userRaffleCount : 0;
                        strategyAwardDTO.setWaitUnLockCount(waitUnCount);
                    }
                    return strategyAwardDTO;
                })
                .collect(Collectors.toList());
        return Response.success(strategyAwardDTOList);
    }

    /**
     * 查询权重列表集合
     *
     * @param requestDTO
     * @return
     */
    @PostMapping("/query_strategy_rule_weight_list")
    public Response<List<StrategyRuleWeightQueryResponseDTO>> queryStrategyRuleWeightList(@RequestBody StrategyRuleWeightQueryRequestDTO requestDTO) {
        // 查询活动信息
        ActivityEntity activityEntity = activitySupport.queryActivity(requestDTO.getActivityId());
        // 查询策略权重规则配置
        StrategyRuleEntity ruleWeightConfig = raffleRule.queryStrategyRule(activityEntity.getStrategyId(), RuleEnums.RuleModelEnum.RULE_WEIGHT);
        // 查询用户总参与活动次数
        RaffleActivityAccountEntity userActivityAccount = activityOrderQuota.queryUserActivityAccount(requestDTO.getUserId(), requestDTO.getActivityId());
        // 构造返回值
        List<StrategyRuleWeightQueryResponseDTO> responseList = Lists.newArrayList();
        if (Objects.nonNull(ruleWeightConfig)) {
            // 解析权重值
            Map<String, List<Integer>> ruleWeightValues = ruleWeightConfig.parseRuleWeightValues();
            // 查询奖品信息
            List<StrategyAwardEntity> strategyAwardList = raffleAward.queryStrategyAwardList(activityEntity.getStrategyId());
            Map<Integer, StrategyAwardEntity> strategyAwardMap = strategyAwardList.stream().collect(Collectors.toMap(StrategyAwardEntity::getAwardId, Function.identity()));
            // 用户总参与抽奖次数
            Integer userPartakeCount = Objects.nonNull(userActivityAccount) ? userActivityAccount.getTotalPartakeCount() : 0;
            // 构造返回值
            for (String configPartakeCount : ruleWeightValues.keySet()) {
                StrategyRuleWeightQueryResponseDTO response = new StrategyRuleWeightQueryResponseDTO();
                response.setUserRaffleActivityTotalCount(userPartakeCount);
                response.setRuleWeightCount(Integer.valueOf(configPartakeCount));
                List<Integer> awardIds = ruleWeightValues.get(configPartakeCount);
                List<StrategyRuleWeightQueryResponseDTO.Award> awardList = awardIds.stream()
                        .map(awardId -> {
                            StrategyRuleWeightQueryResponseDTO.Award award = new StrategyRuleWeightQueryResponseDTO.Award();
                            award.setAwardId(awardId);
                            StrategyAwardEntity strategyAward = strategyAwardMap.get(awardId);
                            String awardTitle = Objects.nonNull(strategyAward) ? strategyAward.getAwardTitle() : "";
                            award.setAwardTitle(awardTitle);
                            return award;
                        }).collect(Collectors.toList());
                response.setAwardList(awardList);
                responseList.add(response);
            }
        }
        return Response.success(responseList);
    }

    /**
     * 随机抽奖接口
     *
     * @param requestDTO 抽奖入参
     * @return 抽奖结果
     */
    @GetMapping("/random_raffle")
    @Override
    public Response<RaffleResponseDTO> raffle(RaffleRequestDTO requestDTO) {
        // 临时使用，目前还未有用户模块
        if (Strings.isEmpty(requestDTO.getUserId())) {
            requestDTO.setUserId("system");
        }
        // 调用抽奖接口
        RaffleParamEntity raffleParam = BeanUtil.copyProperties(requestDTO, RaffleParamEntity.class);
        RaffleResultEntity raffleResult = raffleStrategy.raffle(raffleParam);
        // 构建抽奖返回值
        RaffleResponseDTO raffleResponseDTO = RaffleResponseDTO.builder()
                .awardId(raffleResult.getAwardId())
                .awardIndex(raffleResult.getSort())
                .build();
        return Response.success(raffleResponseDTO);
    }
}
